package com.atguigu.tingshu.live.api;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.live.util.WebSocketLocalContainerUtil;
import com.atguigu.tingshu.model.live.FromUser;
import com.atguigu.tingshu.model.live.SocketMsg;
import com.atguigu.tingshu.model.user.UserInfo;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * @author atguigu-mqx
 * @ClassName WebSocketApiController
 * @description: TODO
 * @date 2023年11月15日
 * @version: 1.0
 */
@Slf4j
@Tag(name = "直播间即时通讯接口管理")
@ServerEndpoint(value = "/api/websocket/{liveRoomId}/{token}")
@Component
public class WebSocketApiController {
    //  声明一个对象
    private static RedisTemplate redisTemplate;
    //  because "this.redisTemplate" is null -- 我们自己编写一个方法，让这个方法跟类一起加载。完成初始化redisTemplate
    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate){
        WebSocketApiController.redisTemplate = redisTemplate;
    }

    //    @Autowired
    //    private RedisTemplate redisTemplate; 由于静态作用！

    /**
     * 获取链接 @PathParam ()-webSocket注解  @PathVariable ->Spring 注解
     * @param session
     * @param liveRoomId
     * @param token
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("liveRoomId") Long liveRoomId, @PathParam("token") String token){
        log.info("建立连接，liveRoomId：{}， token：{}", liveRoomId, token);
        //  将用户信息；保存到集合中。 e67147fd4e1b47018547e349e933f56e
        String userKey = "user:login:"+token;
        //  获取用户信息
        UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(userKey);
        if (null == userInfo) return;
        //  创建对象
        FromUser fromUser = new FromUser();
        fromUser.setUserId(userInfo.getId());
        fromUser.setNickname(userInfo.getNickname());
        fromUser.setAvatarUrl(userInfo.getAvatarUrl());
        //  将用户id与用户信息进行保存.
        WebSocketLocalContainerUtil.addSession(userInfo.getId(),session);
        WebSocketLocalContainerUtil.addFromUser(userInfo.getId(),fromUser);
        WebSocketLocalContainerUtil.addUserIdToLiveRoom(liveRoomId,userInfo.getId());

        //  发送消息：提示谁进入了直播间...
        //构建消息：加入直播间
        SocketMsg socketMsg = WebSocketLocalContainerUtil.buildSocketMsg(liveRoomId, fromUser, SocketMsg.MsgTypeEnum.JOIN_CHAT, fromUser.getNickname()+"加入直播间");
        WebSocketLocalContainerUtil.sendMsg(socketMsg);

    }

    /**
     * 关闭链接
     * @param session
     * @param liveRoomId
     * @param token
     */
    @OnClose
    public void OnClose(Session session, @PathParam("liveRoomId") Long liveRoomId, @PathParam("token") String token){
        System.out.println(liveRoomId+token);
        log.info("关闭连接，liveRoomId：{}， token：{}", liveRoomId, token);
        //  将用户信息；保存到集合中。 e67147fd4e1b47018547e349e933f56e
        String userKey = "user:login:"+token;
        //  获取用户信息
        UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(userKey);
        //  创建对象
        FromUser fromUser = new FromUser();
        fromUser.setUserId(userInfo.getId());
        fromUser.setNickname(userInfo.getNickname());
        fromUser.setAvatarUrl(userInfo.getAvatarUrl());
        //  获取用户Id
        Long userId = userInfo.getId();
        //  构建发送消息对象
        SocketMsg socketMsg = WebSocketLocalContainerUtil.buildSocketMsg(liveRoomId,fromUser, SocketMsg.MsgTypeEnum.CLOSE_SOCKET,fromUser.getNickname()+"离开直播间");

        //  断开直播间的时候，要从集合中删除信息.
        //  将用户id与用户信息进行保存.
        WebSocketLocalContainerUtil.removeSession(userId);
        WebSocketLocalContainerUtil.removeFromUser(userId);
        WebSocketLocalContainerUtil.removeUserIdToLiveRoom(liveRoomId,userId);

        //  谁谁谁离开直播间。
        WebSocketLocalContainerUtil.sendMsg(socketMsg);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message) {
        log.info("来自客户端的消息：{}", message);
        //  发送想消息
//        SocketMsg socketMsg = JSON.parseObject(message, SocketMsg.class);
//        WebSocketLocalContainerUtil.sendMsg(socketMsg);
        //  message:list 频道中发消息！
        redisTemplate.convertAndSend("message:list",message);
    }

    /**
     * 发生错误时调用+
     */
    @OnError
    public void onError(Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }

}
